package service

import (
	"errors"
	"fmt"
	"reflect"

	"mutu/misc"
	"mutu/misc/conf"
	"mutu/misc/log"
	"mutu/models"
)

type BinderManager struct {
}

var (
	BinderService = BinderManager{}
)

func (p BinderManager) ReadUser(m *models.Binder) error {
	var err error
	m.User, err = UserService.GetUserByUuid(m.UserId)
	return err
}

func (p BinderManager) ReadCategory(m *models.Binder) error {

	var err error
	m.Category, err = CategoryService.GetRelCategory(conf.F_Action_Binder, m.Uuid)
	return err
}

func (p BinderManager) ReadTag(m *models.Binder) error {
	var err error
	m.Tags, err = TagService.GetRelTags(conf.F_Action_Binder, m.Uuid)
	return err
}

func (p BinderManager) CreateDefaultUserBinder(userid string) error {
	m := &models.Binder{
		Uuid:   userid,
		Title:  "",
		Desc:   "",
		IsPub:  false,
		UserId: userid,
	}
	return p.CreateBinder(0, nil, m)
}

func (p BinderManager) RemoveDefaultUserBinder(userid string) error {
	return p.DeleteBinder(userid, userid)
}

func (p BinderManager) CreateBinder(cat int, tags []int, m *models.Binder) error {
	if m.Uuid == "" {
		m.Uuid = misc.NewUUID()
	}
	m.Deleted = false

	_, err := models.Orm.Insert(m)
	if err != nil {
		log.Log.Error("创建收藏夹-保存收藏夹出错，%s", err)
		return err
	}

	flag := conf.F_Action_Binder

	if err := CategoryService.CreateRelCategory(cat, flag, m.Uuid); err != nil {
		log.Log.Error("创建收藏夹-保存分类出错，%s", err)
		return err
	}

	if err := TagService.CreateRelTags(tags, flag, m.Uuid); err != nil {
		log.Log.Error("创建收藏夹-保存标签出错，%s", err)
		return err
	}

	return nil
}

func (p BinderManager) EditBinder(cat int, tags []int, m *models.Binder) error {
	nm := &models.Binder{
		Uuid: m.Uuid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("更新收藏夹<%s>-读取原信息出错，%s", nm.Uuid, err)
		return err
	}
	if nm.UserId != m.UserId {
		log.Log.Error("更新收藏夹<%s>失败，没有权限", nm.Uuid)
		return errors.New("没有权限")
	}

	flag := conf.F_Action_Binder

	//解除之前的关联
	if err := CategoryService.ReleaseRelCategory(flag, nm.Uuid); err != nil {
		log.Log.Error("更新收藏夹<%s>-解除分类关系出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.ReleaseRelTags(flag, nm.Uuid); err != nil {
		log.Log.Error("更新收藏夹<%s>-解除标签关系出错，%s", nm.Uuid, err)
		return err
	}

	//创建新的关联
	if err := CategoryService.CreateRelCategory(cat, flag, nm.Uuid); err != nil {
		log.Log.Error("更新收藏夹<%s>-保存收藏夹分类出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.CreateRelTags(tags, flag, nm.Uuid); err != nil {
		log.Log.Error("更新收藏夹<%s>-保存收藏夹标签出错，%s", nm.Uuid, err)
		return err
	}

	var args []string
	if nm.Title != m.Title {
		nm.Title = m.Title
		args = append(args, "Title")
	}
	if nm.Desc != m.Desc {
		nm.Desc = m.Desc
		args = append(args, "Desc")
	}
	if nm.IsPub != m.IsPub {
		nm.IsPub = m.IsPub
		args = append(args, "IsPub")
	}

	if len(args) > 0 {
		args = append(args, "UpdateAt")
		if _, err := models.Orm.Update(nm, args...); err != nil {
			log.Log.Error("更新收藏夹<%s>-保存收藏夹出错，%s", nm.Uuid, err)
			return err
		}
	}

	return nil
}

func (p BinderManager) DeleteBinder(userId, uuid string) error {
	nm := &models.Binder{
		Uuid: uuid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("删除收藏夹-读取原收藏夹<%s>信息出错，%s", nm.Uuid, err)
		return err
	}
	if nm.UserId != userId {
		log.Log.Error("删除收藏夹<%s>失败，没有权限", nm.Uuid)
		return errors.New("没有权限")
	}

	flag := conf.F_Action_Binder

	//解除之前的关联
	if err := CategoryService.ReleaseRelCategory(flag, nm.Uuid); err != nil {
		log.Log.Error("删除收藏夹<%s>-解除分类关系出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.ReleaseRelTags(flag, nm.Uuid); err != nil {
		log.Log.Error("删除收藏夹<%s>-解除标签关系出错，%s", nm.Uuid, err)
		return err
	}

	nm.Deleted = true
	nm.DeleteAt = misc.GTimer.Now
	if _, err := models.Orm.Update(nm, "Deleted", "DeleteAt"); err != nil {
		log.Log.Error("删除收藏夹<%s>-更新收藏夹删除状态出错，%s", nm.Uuid, err)
		return err
	}

	return nil
}

func (p BinderManager) AddItem(userId string, binderid string, relid string) error {
	matter, err := MatterService.GetMatterByUuid(relid)
	if err != nil {
		log.Log.Error("收藏夹<%s>添加<%s>-读取素材信息出错，%s", binderid, relid, err)
		return err
	}

	flag := matter.Flag

	nm := &models.Binder{
		Uuid: binderid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("收藏夹<%s>添加<%d:%s>-读取原收藏夹信息出错，%s", binderid, flag, relid, err)
		return err
	}
	if nm.UserId != userId {
		log.Log.Error("收藏夹<%s>添加<%d:%s>失败，没有权限", binderid, flag, relid)
		return errors.New("没有权限")
	}

	m := &models.BindersMap{
		BinderId: binderid,
		Flag:     flag,
		RelId:    relid,
	}

	if _, err := models.Orm.Insert(m); err != nil {
		log.Log.Debug("typeof err:%v", reflect.TypeOf(err))
		log.Log.Error("收藏夹<%s>添加<%d:%s>出错，%s", binderid, flag, relid, err)
		return err
	}
	return nil
}

func (p BinderManager) RemoveItem(userId string, binderid string, relid string) error {
	matter, err := MatterService.GetMatterByUuid(relid)
	if err != nil {
		log.Log.Error("收藏夹<%s>添加<%s>-读取素材信息出错，%s", binderid, relid, err)
		return err
	}

	flag := matter.Flag

	nm := &models.Binder{
		Uuid: binderid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("收藏夹<%s>移除<%d:%s>-读取原收藏夹信息出错，%s", binderid, flag, relid, err)
		return err
	}
	if nm.UserId != userId {
		log.Log.Error("收藏夹<%s>移除<%d:%s>失败，没有权限", binderid, flag, relid)
		return errors.New("没有权限")
	}

	if _, err := models.Orm.QueryTable("BindersMap").
		Filter("BinderId", binderid).
		Filter("Flag", flag).
		Filter("RelId", relid).Delete(); err != nil {
		log.Log.Debug("typeof err:%v", reflect.TypeOf(err))
		log.Log.Error("收藏夹<%s>移除<%d:%s>出错，%s", binderid, flag, relid, err)
		return err
	}
	return nil
}

func (p BinderManager) GetItems(userId string, binderid string, flag int) ([]*models.Matter, error) {
	nm := &models.Binder{
		Uuid: binderid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("读取收藏夹<%s>内容-读取原收藏夹信息出错，%s", binderid, err)
		return nil, err
	}
	if !nm.IsPub && nm.UserId != userId {
		log.Log.Error("读取收藏夹<%s>内容失败，没有权限", binderid)
		return nil, errors.New("没有权限")
	}

	var arr []*models.Matter

	sql := fmt.Sprintf(`SELECT * FROM matter a where a.uuid in (select rel_id from binders_map b where b.binder_id='%s');`, binderid)
	if _, err := models.Orm.Raw(sql).QueryRows(&arr); err != nil {
		log.Log.Error("读取收藏夹<%s>内容，读取失败，%s", binderid, err)
		return nil, err
	}

	MatterService.FillMattersInfo(arr, true, false, false, false)

	return arr, nil
}

func (p BinderManager) GetUserBinders(userId string) ([]*models.Binder, error) {
	var arr []*models.Binder
	_, err := models.Orm.QueryTable("Binder").Filter("UserId", userId).Filter("Deleted", false).All(&arr)
	if err != nil {
		log.Log.Error("读取用户<%s>, 收藏夹出错，%s", userId, err)
		return nil, err
	}

	return arr, nil
}

func (p BinderManager) GetBinderByUuid(uuid string) (*models.Binder, error) {
	m := &models.Binder{
		Uuid: uuid,
	}
	err := models.Orm.Read(m, "Uuid")
	if err != nil {
		log.Log.Error("读取收藏夹<%s>出错，%s", uuid, err)
		return nil, err
	}

	return m, nil
}

func (p BinderManager) FillBinderInfo(m *models.Binder, fills ...bool) error {

	if len(fills) < 1 || fills[0] {
		p.ReadUser(m)
	}

	if len(fills) < 2 || fills[1] {
		p.ReadCategory(m)
	}

	if len(fills) < 3 || fills[2] {
		p.ReadTag(m)
	}

	return nil
}

func (p BinderManager) FillBindersInfo(arr []*models.Binder, fills ...bool) error {
	for _, item := range arr {
		p.FillBinderInfo(item, fills...)
	}
	return nil
}
